import random
import re
from datetime import datetime

from flask import current_app, jsonify,json,make_response,request,session
from info import constants, db,redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blue


# 获取图片验证码
# 请求路径: /passport/image_code
# 请求方式: GET
# 请求参数: cur_id, pre_id
# 返回值: 图片验证码
@passport_blue.route('/image_code')
def image_code():

    # 获取参数校验参数
    cur_id = request.args.get("cur_id")
    pre_id = request.args.get("pre_id")

    # 校验参数是否为空
    if not cur_id:
        return "图片验证码编号不全"

    # 获取图片验证码
    name, text, image_data = captcha.generate_captcha()

    try:

        # 保存图片验证码到redis中 ， key，value， maxage
        redis_store.set("image_code:%s" % cur_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)

        # 判断是否有上个图片验证码，有则删除
        if not pre_id:
            redis_store.delete("image_code:%s" % pre_id)

    except Exception as e:
        current_app.logger.error(e)
        return "图片验证码保存失败"

    # 返回图片验证码，指定类型让代码更严谨
    response = make_response(image_data)
    response.headers["Content-Type"] = "image/png"

    return response
    # return "helloworld!!!"


#请求路径: /passport/sms_code
# 请求方式: POST
# 请求参数: mobile, image_code,image_code_id
# 返回值: errno, errmsg
# 获取短信验证码
@passport_blue.route('/sms_code',methods=["post"])
def sms_code():
    # 获取参数
    json_data = request.data
    dict_data = json.loads(json_data)
    mobile = dict_data.get("mobile")
    image_code = dict_data.get("image_code")
    image_code = image_code.lower()
    image_code_id = dict_data.get("image_code_id")
    # 校验手机号和验证码是否为空
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno = RET.PARAMERR,errmsg="参数不正确")
    # 校验手机格式是否正确
    if not re.match("1[3-9]\\d{9}",mobile):
        return jsonify(errno = RET.DATAERR,errmsg = "手机号格式不正确")
    #  根据图片编码取出图片验证码
    try:
        redis_image_code = redis_store.get("image_code:%s"% image_code_id)
        redis_image_code = redis_image_code.lower()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="图片验证码获取失败")
    # 判断验证码是否过期
    try:
        if not redis_image_code:
            redis_store.delete("image_code:%s"% image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.NODATA,errmsg= "图片删除失败")
    # 判断图片验证码是否正确
    if image_code != redis_image_code:
        return jsonify(errno= RET.DATAERR,errmsg="验证码错误")
    # 生成短信随机数
    sms_code = "%06d"% random.randint(0,999999)

    # 发送短信
    try:
        ccp = CCP()
        result = ccp.send_template_sms(mobile,[sms_code,5],1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno =RET.THIRDERR, errmsg = "云通讯异常")

    # 如果短信发送失败
    if result == -1:
        return jsonify(errno=RET.DATAERR,errmsg="短信发送失败")

    # 保存短信验证码
    try:
        redis_store.set("sms_code:%s"% mobile,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="手机验证码存储失败")

    # 返回响应
    return jsonify(errno=RET.OK,errmsg="短信发送成功")

# 3.	注册用户
# 请求路径: /passport/register
# 请求方式: POST
# 请求参数: mobile, sms_code,password
# 返回值: errno, errms

@passport_blue.route('/register',methods=["post"])
def register():
    # 获取参数
    # json_data = request.data
    # json_dict = json.loads(json_data)
    json_dict = request.get_json()
    mobile = json_dict.get('mobile')
    sms_code = json_dict.get('sms_code')
    password = json_dict.get('password')

    # 非空校验
    if not all([mobile,sms_code,password]):
        return jsonify(errno=RET.DATAERR,errmsg="不能为空")

    # 获取短信验证码
    try:
        redis_sms_code = redis_store.get("sms_code:%s"% mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取短信验证码失败")

    # 判断短信验证码是否过期
    if not redis_sms_code:
        return jsonify(errno=RET.DATAERR,errmsg="验证码已过期")

    # 删除redis中的短信验证码
    try:
        redis_store.delete("sms_code:%s"% mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA,errmsg="短信验证码删除失败")

    # 验证短信验证码
    if sms_code != redis_sms_code:
        return jsonify(errno=RET.DATAERR,errmsg="短线验证码有误")

    # 创建模型对象，设置属性
    user = User()
    user.nick_name = mobile
    # user.password_hash = password  # 未加密
    user.password = password  # 加密
    user.mobile = mobile
    user.signature = "这个人很懒，什么都没留下！"

    # 存储数据
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="数据存储失败")

    # 返回响应
    return jsonify(errno=RET.OK,errmsg="注册成功")


# 4.	登陆用户
# 请求路径: /passport/login
# 请求方式: POST
# 请求参数: mobile,password
# 返回值: errno, errmsg

@passport_blue.route('/login',methods=["post"])
def login():
    # 获取json数据，mobile,password
    json_dict = request.get_json()
    mobile = json_dict.get("mobile")
    password = json_dict.get("password")

    # 验证数据是否非空
    if not all([mobile,password]):
        return jsonify(errno=RET.NODATA,errmsg="手机号码或者密码不能为空")

    # 通过手机号码获取密码
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(error=RET.DATAERR,errmsg="获取用户信息失败")
    # 判断用户是否存在
    if not user:
        return jsonify(errno=RET.NODATA,errmsg="没有此用户")
    # 校验用户密码是否正确
    if not user.check_passowrd(password):
        return jsonify(errno= RET.PWDERR,errmsg="密码不正确")

    # 记录用户登录信息到session
    session["user_id"] = user.id
    session['nick_name'] = user.nick_name
    session["mobile"] = user.mobile

    # 记录用户最后登录时间
    user.last_login = datetime.now()

    return jsonify(errno=RET.OK,errmsg="登录成功")


# 6.退出登陆
# 请求路径: /passport/logout
# 请求方式: POST
# 请求参数: 无
# 返回值: errno, errmsg

@passport_blue.route('/logout',methods=["post"])
def logout():
    session.pop('user_id',None)
    session.pop("nick_name",None)
    session.pop("mobile",None)

    return jsonify(errno=RET.OK,errmsg="退出成功")

